#include "Spreadsheet.h"
#include "Helper.h"
#include <vector>
#include <string>
using namespace std;

#include "Matrices.h"
#include "PathData.h"
#define _USE_MATH_DEFINES // this makes sure M_PI will be defined
#include <math.h>
#include "fileIO.h"

#include <boost/algorithm/string.hpp>


CPathData::CPathData(void)
{
    _strClassName ="CPathData";
}

CPathData::~CPathData(void)
{
    clear();
}

void CPathData::load(const vector<CSpreadsheet*> &vSpreadsheet_ )
{
    clear();

    CData::load(vSpreadsheet_);
    //load init file
    {
        CSpreadsheet *pInit;
        for(unsigned int i=0;i<vSpreadsheet_.size();i++)
        {
            if(vSpreadsheet_[i]->currentFile().contains(".init"))
                pInit = vSpreadsheet_[i];
        }
        if(!pInit)
        {
            QString sError("Init File : can not find any init file.\n \"");
            sError += pInit->currentFile();
            sError += "\".\n";
            throw exception(sError.toStdString().c_str());
        }
        vector<double> vIn;
        pInit->search("PostRadius",1,&vIn);           setPostRadius() = vIn[0];
        pInit->search("Post Height",1,&vIn);          setPostHeight() = vIn[0];
        pInit->search("PostNumber",1,&vIn);           setPostNum() = vIn[0];
        pInit->search("GroundX",1,&vIn);              setGroundX() = vIn[0];
        pInit->search("GroundZ",1,&vIn);              setGroundZ() = vIn[0];
        pInit->search("cloudy3DDotNum",1,&vIn);       setCloudy3DDotNum() = vIn[0];
        pInit->search("numSquares",1,&vIn);           setNumSquares() = vIn[0];
        pInit->search("DotColor",4,&setDotColor());
        pInit->search("Post removal",1,&vIn);         setPostRemoval() = vIn[0];
        pInit->search("DotSize",1,&vIn);              setDotSize() = vIn[0];
        pInit->search("TextureColor",4,&setTextureColor());        
    }
    return;
}

bool CPathData::trialFinished()
{
    return timeIdx()>=60*60;
}


void CPathData::precompute()
{
    CData::precompute();
}

void CPathData::precomputeEachTrial()
{
    precomputePathDirect();
}

void CPathData::precomputePathDirect()
{
    setTimeIdx() = 0;
    int nTotalFrame = 60*60;
    setEyePath().SetSize(nTotalFrame,3,0);
    setObserverDirect().SetSize(nTotalFrame,3,0);
    SetRoll()            .SetSize(nTotalFrame,1,0);
    SetYaw()             .SetSize(nTotalFrame,1,0);
    SetPitch()           .SetSize(nTotalFrame,1,0);
    SetObserverUpVecRef().SetSize(nTotalFrame,3,0);
    SetObserverUpVec()   .SetSize(nTotalFrame,3,0);
    //int nTrialIdx = trialIdx();
    //double dForwardVelocity = GetRunScript()(nTrialIdx,1);
}

void CPathData::clear()
{
    CData::clear();
}


void CPathData::saveToFile()
{
   return;
}

void CPathData::afterCompute()
{
}

bool CPathData::preRunFinished()
{
    if (timeIdx() < 60*60) 
        return false;
    else
        return true;
}

void CPathData::parser(const string& strCondition_, vector<int>* pvConds_ )
{
    pvConds_->clear();
    vector<string> vCond;
    boost::split( vCond, strCondition_, boost::is_any_of("+"), boost::token_compress_on );
    for(int i=0;i<(int)vCond.size();i++)
    {
        //if(vCond[i]==string("L"))         //lane marker
        //    pvConds_->push_back(0);
        if(vCond[i]==string("P"))    //post
            pvConds_->push_back(0);
        else if(vCond[i]==string("T1G"))   //textured ground
            pvConds_->push_back(1);
        else if(vCond[i]==string("T1GC"))  //textured ground + celing 
            pvConds_->push_back(2);
        else if(vCond[i]==string("T2G"))   //textured ground
            pvConds_->push_back(3);
        else if(vCond[i]==string("T2GC"))  //textured ground + celing 
            pvConds_->push_back(4);
        else if(vCond[i]==string("UGZ"))  //uniform ground w.r.t. Z
            pvConds_->push_back(11);
        else if(vCond[i]==string("UGZC"))  //uniform w.r.t. z + ceiling 
            pvConds_->push_back(12);
        else if(vCond[i]==string("UGZSp"))  //uniform ground w.r.t. z Sphere
            pvConds_->push_back(13);
        else if(vCond[i]==string("UGZCSp"))  //uniform ground w.r.t. z Sphere + ceiling
            pvConds_->push_back(14);
        else if(vCond[i]==string("UGZDi"))  //uniform ground w.r.t. z Disc
            pvConds_->push_back(15);
        else if(vCond[i]==string("UGZCDi"))  //uniform ground w.r.t. z Disc + ceiling
            pvConds_->push_back(16);
        else if(vCond[i]==string("UGZF"))//uniform cloud with limited life time
            pvConds_->push_back(111);
        else if(vCond[i]==string("UGZCF"))//uniform cloud with limited life time
            pvConds_->push_back(121);
        else if(vCond[i]==string("UG"))   //uniform ground
            pvConds_->push_back(21);
        else if(vCond[i]==string("UGF"))//uniform cloud with limited life time
            pvConds_->push_back(211);
        else if(vCond[i]==string("UGC"))  //uniform ground + ceiling
            pvConds_->push_back(22);
        else if(vCond[i]==string("UGCF"))//uniform cloud with limited life time
            pvConds_->push_back(221);
        else if(vCond[i]==string("UGSp"))   //uniform ground sphere
            pvConds_->push_back(23);
        else if(vCond[i]==string("UGCSp"))  //uniform ground sphere + ceiling
            pvConds_->push_back(24);
        else if(vCond[i]==string("UGDi"))   //uniform ground Disc
            pvConds_->push_back(25);
        else if(vCond[i]==string("UGCDi"))  //uniform random Disc + ceiling
            pvConds_->push_back(26);
        else if(vCond[i]==string("DG"))   //de-perspective ground
            pvConds_->push_back(31);
        else if(vCond[i]==string("DGF"))   //de-perspective ground
            pvConds_->push_back(311);
        else if(vCond[i]==string("DGC"))  //de-perspective ground + ceiling
            pvConds_->push_back(32);
        else if(vCond[i]==string("DGCF"))  //de-perspective ground + ceiling
            pvConds_->push_back(321);
        else if(vCond[i]==string("DGSp"))   //de-perspective ground sphere
            pvConds_->push_back(33);
        else if(vCond[i]==string("DGCSp"))  //de-perspective ground sphere + ceiling
            pvConds_->push_back(34);
        else if(vCond[i]==string("DGDi"))   //de-perspective ground Disc
            pvConds_->push_back(35);
        else if(vCond[i]==string("DGCDi"))  //de-perspective ground Disc + ceiling
            pvConds_->push_back(36);
        else if(vCond[i]==string("UCl"))  //uniform cloud
            pvConds_->push_back(41);
        else if(vCond[i]==string("UClSp"))  //uniform cloud sphere
            pvConds_->push_back(42);
        else if(vCond[i]==string("UClF"))  //uniform cloud sphere
            pvConds_->push_back(411);
        else if(vCond[i]==string("UClZ")) //uniform cloud w.r.t. z
            pvConds_->push_back(43);
        else if(vCond[i]==string("UClZF")) //uniform cloud w.r.t. z
            pvConds_->push_back(431);
        else if(vCond[i]==string("UClZSp"))//uniform cloud w.r.t. z sphere
            pvConds_->push_back(44);
        else if(vCond[i]==string("SG"))   //solid ground
            pvConds_->push_back(51);
        else if(vCond[i]==string("SGC"))  //solid ground + ceiling
            pvConds_->push_back(52);
        else if(vCond[i]==string("UGCl"))  //uniform ground equated cloud 
            pvConds_->push_back(61);
        else if(vCond[i]==string("UGCCl"))  //uniform ground + ceiling equated cloud 
            pvConds_->push_back(62);
        else if(vCond[i]==string("UGZCl"))  //uniform ground w.r.t. z equated cloud
            pvConds_->push_back(71);
        else if(vCond[i]==string("UGZCCl"))  //uniform ground w.r.t. z + ceiling equated cloud
            pvConds_->push_back(72);
        else if(vCond[i]==string("DGCl"))  //de-perspective ground equated cloud
            pvConds_->push_back(81);
        else if(vCond[i]==string("DGCCl"))  //de-perspective ground + ceiling equated cloud
            pvConds_->push_back(82);
        else if(vCond[i]==string("T"))    //target
            pvConds_->push_back(91);
        else if(vCond[i]==string("TP"))  //target post
            pvConds_->push_back(92);
        else
        {
            QString sError("Script File : unrecognized rendering condition.\n \"");
            sError += scriptFileName();
            sError += "\".\n";
            throw exception(sError.toStdString().c_str());
        }
    }
}